<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/jsp/commons/include.jsp"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<title>JavaScript Demo</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link />
	<style type="text/css">
		#container{
		    width: 760px;
		    height: 600px;
		    margin: 30px auto;
		    /* IE fix 居中布局 */
		    text-align: center;
		}
		 
		#main{
		    width: 760px;
		    height: 600px;
		    margin: 30px auto;
		    /* IE fix 居中布局 */
		 	text-align: left;
		}
	</style>
	
	<script type="text/javascript">
		/*
			Javascript 面向对象编程
			http://coolshell.cn/articles/6441.html
		*/
		var newLine = "<br/>";	
		
		//====================================================================
		
		document.write("Prototype 和 继承" + newLine);
		
		var plus = function(x,y){
		    document.write( x + ' + ' + y + ' = ' + (x+y) + '<br>');
		    return x + y;
		};
		 
		var minus = function(x,y){
		    document.write(x + ' - ' + y + ' = ' + (x-y) + '<br>');
		    return x - y;
		};
		 
		var operations = {
		    '+': plus,
		    '-': minus
		};
		 
		var calculate = function(x, y, operation){
		    return operations[operation](x, y);
		};
		 
		calculate(12, 4, '+');
		calculate(24, 3, '-');
		
		// 我们能不能把这些东西封装起来呢，我们需要使用prototype
		
		var Cal = function(x, y){
		    this.x = x;
		    this.y = y;
		}
		 
		Cal.prototype.operations = {
		    '+': function(x, y) { return x+y;},
		    '-': function(x, y) { return x-y;}
		};
		 
		Cal.prototype.calculate = function(operation){
		    return this.operations[operation](this.x, this.y);
		};
		 
		var c = new Cal(4, 5);
		
		
		document.write(c.calculate('+'));
		document.write(newLine);
		document.write(c.calculate('-'));
		document.write(newLine);
		
		// 创建一个Student来继承Person
		function Person(name, email, website){
		    this.name = name;
		    this.email = email;
		    this.website = website;
		};
		 
		Person.prototype.sayHello = function(){
		    var hello = "Hello, I am "+ this.name  + ", <br>" +
		                "my email is: " + this.email + ", <br>" +
		                "my website is: " + this.website;
		    return hello;
		};
		 
		function Student(name, email, website, no, dept){
		    var proto = Object.getPrototypeOf;
		    proto(Student.prototype).constructor.call(this, name, email, website);
		    this.no = no;
		    this.dept = dept;
		}
		 
		// 继承prototype
		Student.prototype = Object.create(Person.prototype);
		 
		//重置构造函数
		Student.prototype.constructor = Student;
		 
		//重载sayHello()
		Student.prototype.sayHello = function(){
		    var proto = Object.getPrototypeOf;
		    var hello = proto(Student.prototype).sayHello.call(this) + '<br>';
		    hello += "my student no is: " + this. no + ", <br>" +
		             "my departent is: " + this. dept;
		    return hello;
		};
		 
		var me = new Student(
		    "Chen Hao",
		    "haoel@hotmail.com",
		    "http://coolshell.cn",
		    "12345678",
		    "Computer Science"
		);
		document.write(me.sayHello());
		document.write('<hr/>');
		
		//====================================================================
			
		document.write("兼容性" + newLine);
		
		// Object.create()函数
		function clone(proto) {
		    function Dummy() { }
		 
		    Dummy.prototype             = proto;
		    Dummy.prototype.constructor = Dummy;
		 
		    return new Dummy(); //等价于Object.create(Person);
		}
		 
		var me = clone(Person);
		
		// defineProperty()函数
		function defineProperty(target, key, descriptor) {
		    if (descriptor.value){
		        target[key] = descriptor.value;
		    }else {
		        descriptor.get && target.__defineGetter__(key, descriptor.get);
		        descriptor.set && target.__defineSetter__(key, descriptor.set);
		    }
		 
		    return target
		}
		
		// keys()函数
		function keys(object) { var result, key
		    result = [];
		    for (key in object){
		        if (object.hasOwnProperty(key))  result.push(key)
		    }
		 
		    return result;
		}
		
		// Object.getPrototypeOf()函数
		function proto(object) {
		    return !object?                null
		         : '__proto__' in object?  object.__proto__
		         : /* not exposed? */      object.constructor.prototype
		}
		
		// bind函数
		var slice = [].slice
 
		function bind(fn, bound_this) { var bound_args
		    bound_args = slice.call(arguments, 2)
		    return function() { var args
		        args = bound_args.concat(slice.call(arguments))
		        return fn.apply(bound_this, args) }
		}
	</script>
</head>

<body>
	<div id="container">
		<div id="main">
				
		</div>
	</div>
</body>
</html>
